home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 6 / Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso / 020a / dvpt20.zip / ULAW.C < prev    next >
C/C++ Source or Header  |  1991-12-12  |  6KB  |  285 lines

  1. /****************************************************************/
  2. /*                                                              */
  3. /*             Digitized Voice Programmer's Toolkit             */
  4. /*             ------------------------------------             */
  5. /*                                                              */
  6. /*                  Simple Mu-Law File Encoder                  */
  7. /*                                                              */
  8. /*            Copyright (c) 1991, Farpoint Software             */
  9. /*                                                              */
  10. /****************************************************************/
  11.  
  12. /* This source file is not commented, but it is relatively easy */
  13. /* to follow. The program reads a voice data file and writes an */
  14. /* output file which has been compressed 2:1 by encoding each   */
  15. /* sample (byte) into a nybble extracted from a lookup table.   */
  16. /* The lookup table approximates a highly quantized version of  */
  17. /* the standard Mu-Law curve widely used in telephone communi-  */
  18. /* cations.                                                     */
  19.  
  20.  
  21. #include <stdlib.h>
  22. #include <fcntl.h>
  23. #include <io.h>
  24. #include <sys\types.h>
  25. #include <sys\stat.h>
  26. #include <stdio.h>
  27. #include <stddef.h>
  28. #include <malloc.h>
  29.  
  30. /*-------------------------------------------------------------------*/
  31.  
  32. char logo[] = "Simple Mu-Law File Encoder\r\n"
  33.  "Copyright(c) 1991, Farpoint Software\r\n";
  34.  
  35. unsigned char *s_buffer;
  36. unsigned char *d_buffer;
  37. int s_handle,d_handle;
  38. long histogram[256];
  39.  
  40. int ctable[256] =
  41.     {
  42. // 33 slots
  43.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  44. // 48 slots
  45.     1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
  46.     1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
  47. // 24 slots
  48.     2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
  49. // 12 slots
  50.     3,3,3,3,3,3,3,3,3,3,3,3,
  51. // 6 slots
  52.     4,4,4,4,4,4,
  53. // 3 slots
  54.     5,5,5,
  55. // 1 slots
  56.     6,
  57. // 1 slots
  58.     7,
  59. // 1 slots
  60.     8,
  61. // 1 slots
  62.     9,
  63. // 3 slots
  64.     10,10,10,
  65. // 6 slots
  66.     11,11,11,11,11,11,
  67. // 12 slots
  68.     12,12,12,12,12,12,12,12,12,12,12,12,
  69. // 24 slots
  70.     13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
  71.     13,13,13,13,
  72. // 48 slots
  73.     14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,
  74.     14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,
  75.     14,14,14,14,14,14,14,14,
  76. // 33 slots
  77.     15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
  78.     15,15,15,15,15,15,15,15,15,15,15,15,15
  79.     };
  80.  
  81. char errmsg1[] = "File read error.";
  82. char errmsg2[] = "File write error.";
  83. char errmsg3[] = "Unable to allocate memory.";
  84.  
  85. /*-------------------------------------------------------------------*/
  86.  
  87. void main(argc,argv)
  88. int argc;
  89. char **argv;
  90.  
  91. {
  92. long s_len;
  93. unsigned int blocks, oddblock;
  94. unsigned int i, j;
  95. int adjustment;
  96. long histmax1, histmax2;
  97. unsigned int index1, index2;
  98. int tempvar;
  99.  
  100. puts(logo);
  101.  
  102. for ( i = 0 ; i < 256 ; i++ )
  103.     histogram[i] = 0L;
  104.  
  105. if (argc != 3)
  106.     {
  107.     puts("\nCommand line:");
  108.     puts(" ULAW <source file> <dest file>\n");
  109.     exit(1);
  110.     }
  111.  
  112. argv++;
  113. s_handle = open(*argv,O_BINARY|O_RDONLY);
  114. if (s_handle == -1)
  115.     {
  116.     puts(errmsg1);
  117.     exit(1);
  118.     }
  119. argv++;
  120. d_handle = open(*argv,O_BINARY|O_RDWR|O_CREAT|O_TRUNC,S_IREAD|S_IWRITE);
  121. if (d_handle == -1)
  122.     {
  123.     close(s_handle);
  124.     puts(errmsg2);
  125.     exit(1);
  126.     }
  127.  
  128. s_buffer = (unsigned char *)malloc(32768U);
  129. if (s_buffer == NULL)
  130.     {
  131.     puts(errmsg3);
  132.     close(s_handle);
  133.     close(d_handle);
  134.     exit(1);
  135.     }
  136.  
  137. d_buffer = (unsigned char *)malloc(16384U);
  138. if (d_buffer == NULL)
  139.     {
  140.     puts(errmsg3);
  141.     free(s_buffer);
  142.     close(s_handle);
  143.     close(d_handle);
  144.     exit(1);
  145.     }
  146.  
  147. s_len = filelength(s_handle);
  148.  
  149. blocks = (unsigned int)(s_len >> 15);
  150. oddblock = (unsigned int)(s_len & 0x7FFF);
  151.  
  152. for ( i = 0 ; i < blocks ; i++ )
  153.     {
  154.     if ( read(s_handle, s_buffer, 32768U) != 32768U )
  155.         {
  156.         close(s_handle);
  157.         close(d_handle);
  158.         free(s_buffer);
  159.         free(d_buffer);
  160.         puts(errmsg1);
  161.         exit(1);
  162.         }
  163.     for ( j = 0 ; j < 32768U ; j++ )
  164.         histogram[s_buffer[j]]++;
  165.     }
  166. if ( oddblock )
  167.     {
  168.     if ( (unsigned int)read(s_handle, s_buffer, oddblock) != oddblock )
  169.         {
  170.         close(s_handle);
  171.         close(d_handle);
  172.         free(s_buffer);
  173.         free(d_buffer);
  174.         puts(errmsg1);
  175.         exit(1);
  176.         }
  177.     for ( j = 0 ; j < oddblock ; j++ )
  178.         histogram[s_buffer[j]]++;
  179.     }
  180.  
  181. lseek(s_handle, 0L, SEEK_SET);
  182.  
  183. histmax1 = 0L;
  184. histmax2 = 0L;
  185. index1 = 0;
  186. index2 = 0;
  187. for ( i = 0 ; i < 256 ; i++ )
  188.     {
  189.     if ( histmax1 < histogram[i] )
  190.         {
  191.         histmax1 = histogram[i];
  192.         index1 = i;
  193.         }
  194.     }
  195. for ( i = 0 ; i < 256 ; i++ )
  196.     {
  197.     if ( i != index1 )
  198.         {
  199.         if ( histmax2 < histogram[i] )
  200.             {
  201.             histmax2 = histogram[i];
  202.             index2 = i;
  203.             }
  204.         }
  205.     }
  206. if ( abs(index1 - index2) > 8 )
  207.     adjustment = 0;
  208. else
  209.     adjustment = 0x7F - ((int)(index1 + index2) / 2);
  210.  
  211. for ( i = 0 ; i < blocks ; i++ )
  212.     {
  213.     if ( read(s_handle, s_buffer, 32768U) != 32768U )
  214.         {
  215.         close(s_handle);
  216.         close(d_handle);
  217.         free(s_buffer);
  218.         free(d_buffer);
  219.         puts(errmsg1);
  220.         exit(1);
  221.         }
  222.     for ( j = 0 ; j < 32768U ; j++ )
  223.         {
  224.         tempvar = s_buffer[j] + adjustment;
  225.         if ( tempvar < 0 )
  226.             tempvar = 0;
  227.         else if ( tempvar > 255 )
  228.             tempvar = 255;
  229.         s_buffer[j] = (unsigned char)tempvar;
  230.         }
  231.     for ( j = 0 ; j < 16384 ; j++ )
  232.         d_buffer[j] = (unsigned char)(ctable[s_buffer[2*j]] |
  233.             (ctable[s_buffer[2*j+1]] << 4) );
  234.     if ( write(d_handle, d_buffer, 16384U) != 16384U )
  235.         {
  236.         close(s_handle);
  237.         close(d_handle);
  238.         free(s_buffer);
  239.         free(d_buffer);
  240.         puts(errmsg2);
  241.         exit(1);
  242.         }
  243.     }
  244. if ( oddblock )
  245.     {
  246.     if ( (unsigned int)read(s_handle, s_buffer, oddblock) != oddblock )
  247.         {
  248.         close(s_handle);
  249.         close(d_handle);
  250.         free(s_buffer);
  251.         free(d_buffer);
  252.         puts(errmsg1);
  253.         exit(1);
  254.         }
  255.     for ( j = 0 ; j < oddblock ; j++ )
  256.         {
  257.         tempvar = s_buffer[j] + adjustment;
  258.         if ( tempvar < 0 )
  259.             tempvar = 0;
  260.         else if ( tempvar > 255 )
  261.             tempvar = 255;
  262.         s_buffer[j] = (unsigned char)tempvar;
  263.         }
  264.     for ( j = 0 ; j < oddblock / 2 ; j++ )
  265.         d_buffer[j] = (unsigned char)(ctable[s_buffer[2*j]] |
  266.             (ctable[s_buffer[2*j+1]] << 4) );
  267.     if ( (unsigned int)write(d_handle, d_buffer, oddblock / 2) != oddblock / 2 )
  268.         {
  269.         close(s_handle);
  270.         close(d_handle);
  271.         free(s_buffer);
  272.         free(d_buffer);
  273.         puts(errmsg2);
  274.         exit(1);
  275.         }
  276.     }
  277.  
  278. puts("File compression complete.");
  279. close(s_handle);
  280. close(d_handle);
  281. free(s_buffer);
  282. free(d_buffer);
  283. exit(0);
  284. }
  285.